<?php
namespace lib;
use think\Db;
use lib\Curl;
class Paywechat{
	public $order=[];							//全局订单数据
	public $log_path='';							//日志路径
	public $arr=[];								//组装后的数据
	public $notify="http://www.fanshangxi.cn/web/Notify/wechat";		//回调地址
	public $appid='wxd0465d5af41c5968';
	public $mch_id='1509281041';
	public $keyval='192006250b4c09247ec02edce69f6a2d';
	protected $xmlstr='';
	public function __construct($order){
		$this->order=$order;
	}
	public function set_notify($url){
		$this->notify=$url;
	}
	public function set_appid($appid){
		$this->appid=$appid;
	}
	public function set_mch_id($mch_id){
		$this->mch_id=$mch_id;
	}
	public function set_keyval($keyval){
		$this->keyval=$keyval;
	}
	//获取jsapi支付的配置数据
	public function js_pay(){
		$rel=$this->prepay();
		if($rel['code']<0){
			return $rel;
		}else{
			$prepay_id=$rel['result']['prepay_id'];
			$arr=[
				'appId'		=> $this->appid,
				'timeStamp'	=> time(),
				'nonceStr'	=> nonce_str(),
				'package'	=> 'prepay_id='.$prepay_id,
				'signType'	=> 'MD5'
			];
			$this->arr=$arr;
			$this->sign();
			return rel(1,'获取预支付成功',$this->arr);
		}
	}
	//支付预请求
	public function prepay(){
		$this->log_path='log/error/prepay.txt';
		$this->createPayData();
		$this->payXml();
		$rel=$this->put('https://api.mch.weixin.qq.com/pay/unifiedorder');
		return $rel;
	}
	//查询订单
	public function query(){
		$this->log_path='log/error/query.txt';
		$this->createQueryData();
		$this->queryXml();
		$rel=$this->put('https://api.mch.weixin.qq.com/pay/orderquery');
		return $rel;
	}
	//构建支付订单数据
	public function createPayData(){
		$order=$this->order;
		$arr=[
			'openid'			=> $order['openid'],
			'attach'			=> $order['type'],		 	//自定义数据，订单类型
			'body'				=> $order['order_name'], 	//商品主体
			'notify_url'		=> $this->notify,		 	//支付回调地址
			'out_trade_no'		=> $order['order_a'],	 	//商户订单号
			'spbill_create_ip'	=> $order['addip'],	 		//终端IP
			'total_fee' 		=> $order['total_price']*100,  //订单总金额，单位为分
			'sign_type'			=> 'MD5',
			'trade_type'		=> 'JSAPI'					//微信支付下单类型
		];
		$arr['appid'] 		=$this->appid;
		$arr['mch_id']		=$this->mch_id;
		$arr['nonce_str']	=nonce_str();
		$this->arr=$arr;
		$this->sign();
	}
	//构建查询订单数据
	public function createQueryData(){
		$order=$this->order;
		if(isset($order['order_a'])){
			$arr['out_trade_no ']=$order['order_a'];
		}else{
			$arr['transaction_id']=$order['order_b'];
		}
		$arr['appid'] 		=$this->appid;
		$arr['mch_id']		=$this->mch_id;
		$arr['nonce_str']	=nonce_str();
		$this->arr=$arr;
		$this->sign();
	}
	//统一签名方法
	protected function sign(){
		$arr=$this->arr;
		ksort($arr);
		$buff = "";
		foreach ($arr as $k => $v){
			if($k != "sign" && $v != "" && !is_array($v)){
				$buff .= $k . "=" . $v . "&";
			}
		}
//		$stringA = trim($buff, "&");
		$stringSignTemp=$buff.'key='.$this->keyval;
		$sign=strtoupper(md5($stringSignTemp));
		$this->arr['sign']=$sign;
	}
	//组装预支付的xml数据
	protected function payXml(){
		/*注意：如果拼接的数据，例如本地订单号是非纯数字，应该使用<![CDATA[%s]]>包裹*/
		$xmltwo=<<<EOT
<xml>
    <appid><![CDATA[%s]]></appid>
    <attach><![CDATA[%s]]></attach>
    <body><![CDATA[%s]]></body>
    <mch_id>%s</mch_id>
    <nonce_str><![CDATA[%s]]></nonce_str>
    <notify_url><![CDATA[%s]]></notify_url>
    <openid><![CDATA[%s]]></openid>
    <out_trade_no>%s</out_trade_no>
    <sign_type><![CDATA[%s]]></sign_type>
    <spbill_create_ip><![CDATA[%s]]></spbill_create_ip>
    <total_fee>%s</total_fee>
    <trade_type><![CDATA[%s]]></trade_type>
    <sign><![CDATA[%s]]></sign>
 </xml> 
EOT;
		$this->xmlstr=sprintf($xmltwo,
		$this->arr['appid'],
		$this->arr['attach'],
		$this->arr['body'],
		$this->arr['mch_id'],
		$this->arr['nonce_str'],
		$this->arr['notify_url'],
		$this->arr['openid'],
		$this->arr['out_trade_no'],
		$this->arr['sign_type'],
		$this->arr['spbill_create_ip'],
		$this->arr['total_fee'],
		$this->arr['trade_type'],
		$this->arr['sign']);
	}
	//统一发送xml数据方法
	protected function put($url){
		$xmlstr=$this->xmlstr;
		libxml_disable_entity_loader(true);
		$rel=Curl::https_curl($url,$xmlstr);
		$xmlob=simplexml_load_string($rel,'SimpleXMLElement',LIBXML_NOCDATA);
		$xml_json=json_encode($xmlob);
		$xml_arr=json_decode($xml_json,1);
//		dump($xml_arr);
		if($xml_arr['return_code']=='SUCCESS'){
			return rel(1,'获取数据成功',$xml_arr);
		}else{
			$this->log($xml_arr);
			return rel(-1,$xml_arr['return_msg']);
		}
	}
	//组装查询的xml数据
	protected function queryXml(){
		$order=$this->order;
		if(isset($order['order_a'])){//采用本地订单查询
			$order_code=$order['order_a'];
			$xmltwo=<<<EOT
<xml>
    <appid><![CDATA[%s]]></appid>
    <mch_id>%s</mch_id>
    <nonce_str><![CDATA[%s]]></nonce_str>
    <out_trade_no>%s</out_trade_no>
    <sign><![CDATA[%s]]></sign>
 </xml>
EOT;
		}else{
			$order_code=$order['order_b'];
			$xmltwo=<<<EOT
<xml>
    <appid><![CDATA[%s]]></appid>
    <mch_id>%s</mch_id>
    <nonce_str><![CDATA[%s]]></nonce_str>
    <transaction_id>%s</transaction_id>
    <sign><![CDATA[%s]]></sign>
 </xml>
EOT;
		}
		
		$this->xmlstr=sprintf($xmltwo,
		$this->arr['appid'],
		$this->arr['mch_id'],
		$this->arr['nonce_str'],
		$order_code,
		$this->arr['sign']);
	}
	/**
	 * 写入日志
	 * @param $status 	日志类型  1错误日志 2成功日志
	 * @param $extra	额外参数（可选）
	 */
	protected function log($xml_arr){
		$log_path=$this->log_path;
		$order=$this->order;
		$arr=$this->arr;
		$xmlstr=$this->xmlstr;
		$content='';
		$content.='响应时间：'.date('Y/m/d H:i:s',time())."\r\n";
		$content.="------------------------------------------------------------------------------------\r\n";
		$content.="响应数据：\r\n";
		foreach($xml_arr as $k=>$v){
			if(is_array($v)){
				$content."二维数据{$k}：\r\n";
				foreach($v as $k2=>$v2){
					if(is_array($v2)){
						$content.=$k2."===>".json_encode($v2)."\r\n";
					}else{
						$content.=$k2."===>".$v2."\r\n";
					}
				}
			}else{
				$content.=$k."===>".$v."\r\n";
			}
		}
		$content.="------------------------------------------------------------------------------------\r\n";
		$content.="请求数据：\r\n";
		foreach($arr as $k=>$v){
			if(is_array($v)){
				$content."二维数据{$k}：\r\n";
				foreach($v as $k2=>$v2){
					if(is_array($v2)){
						$content.=$k2."===>".json_encode($v2)."\r\n";
					}else{
						$content.=$k2."===>".$v2."\r\n";
					}
				}
			}else{
				$content.=$k."===>".$v."\r\n";
			}
		}
		$content.="------------------------------------------------------------------------------------\r\n";
		$content.="订单数据：\r\n";
		foreach($order as $k=>$v){
			$content.=$k."===>".$v."\r\n";
		}
		$content.="请求的xml数据：\r\n";
		$content.=$xmlstr;
		$content.="=====================================================================================\r\n\r\n";
		file_put_contents($log_path,$content,FILE_APPEND);
	}
}
